<template>
  <div class="os-container">
    <div class="section-container">
      <div class="section-title">用户管理</div>
      <div class="section-actions">
        <div class="actions-left">
          <el-button v-if="userInfo.isSystem" v-permission="['setting:permission:group:add']" type="primary" @click="handleAdd">添加团队</el-button>
          <SearchCmp v-if="searchCmpArray.length" :searchCmpArray="searchCmpArray" :searchForm="queryData" @onSubmit="handleSearch" />
        </div>
      </div>
      <el-row class="content-box">
        <el-col :span="5" class="menu-tree-box">
          <div class="tree-header">
            <span class="tree-header-title">团队名称</span>
          </div>
          <el-scrollbar style="height: calc(100vh - 288px);">
            <el-tree v-loading="treeLoading" :data="treeData" :props="oStructureTreeProps" node-key="id" :expand-on-click-node="false" @node-click="treeNodeClick" :indent="0" class="tree-content">
              <template #default="{ node, data }">
                <div class="custom-tree-node">
                  <div class="tree-node-label" :style="{ paddingLeft: (node.level - 1) * 10 + 'px' }" :title="node.label">
                    <i class="iconfont">&#xe6a7;</i>
                    {{ node.label }}
                  </div>
                  <div class="tree-options">
                    <el-dropdown>
                      <i class="iconfont">&#xe78d;</i>
                      <template #dropdown>
                        <el-dropdown-menu>
                          <el-dropdown-item v-if="hasPermission(['setting:permission:group:add'])"><el-button type="primary" link @click="handleAdd(data)">新增</el-button></el-dropdown-item>
                          <el-dropdown-item v-if="hasPermission(['setting:permission:group:edit'])"><el-button type="primary" link @click="handleEdit(data)">编辑</el-button></el-dropdown-item>
                          <!-- 禁止删除自身所在团队，超管不限制 -->
                          <el-dropdown-item v-if="hasPermission(['setting:permission:group:delete']) && userInfo.groupId !== data.id">
                            <el-button type="danger" link @click="handleDelete(data)">删除</el-button>
                          </el-dropdown-item>
                        </el-dropdown-menu>
                      </template>
                    </el-dropdown>
                  </div>
                </div>
              </template>
            </el-tree>
          </el-scrollbar>
        </el-col>
        <el-col :span="19" class="user-table">
          <div class="user-table-top">
            <div class="top-left">
              <span class="curOStructure" v-if="curOStructure">{{ curOStructure.name }}</span>
              <span class="user-default-show" v-else>未选择团队，默认展示所有人员</span>
              <span class="user-total">{{ `（${tableData?.length || 0}人）` }}</span>
              <el-button type="primary" v-if="curOStructure" link @click="showAllUser">查看全部</el-button>
            </div>
            <div class="top-right">
              <el-button v-permission="['setting:permission:user:add']" type="primary" size="small" @click="handleAddUser">添加成员</el-button>
              <el-button v-permission="['setting:permission:user:edit']" type="danger" size="small" :disabled="!checkedList?.length" @click="handleTransfer">转移</el-button>
            </div>
          </div>
          <RuifoxTable :loading="tableLoading" :default-index="false" :default-checkbox="true" v-model:tableData="tableData" v-model:fieldList="fieldList">
            <template #default-checkbox="{ element }">
              <div class="table-div-check">
                <el-checkbox class="unmover" v-model="element.checked" @change="handleCheckTable(element.id)" />
              </div>
            </template>
            <template #roleNames="{ element }">
              <div class="role-names-box">
                <el-tag v-for="(item, index) in element.roleNames" :key="index">{{ item }}</el-tag>
              </div>
            </template>
            <template #isBan="{ element }">
              <el-switch v-model="element.state" :active-value="0" :inactive-value="1" :before-change="() => beforeChange(element)" />
            </template>
            <template #groupName="{ element }">
              <div class="group-name-box">
                <el-tag>{{ element.groupName }}</el-tag>
              </div>
            </template>
            <template #options="{ element }">
              <div class="table-td-option">
                <el-button v-permission="['setting:permission:user:edit']" link type="primary" size="small" @click="handleEditPermission(element)">菜单权限</el-button>
                <el-button v-permission="['setting:permission:user:edit']" link type="primary" size="small" @click="handleBindResourceAuthGroup(element)">绑定策略</el-button>
                <el-button v-permission="['setting:permission:user:edit']" link type="primary" size="small" @click="handleEditUser(element)">编辑</el-button>
                <el-dropdown class="more-icon-box">
                  <i class="iconfont more-icon" style="cursor: pointer">&#xe78d;</i>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item v-if="hasPermission(['setting:permission:user:edit'])" @click="handleEditResourceAuth(element)">绑定资源</el-dropdown-item>
                      <el-dropdown-item v-if="hasPermission(['setting:permission:user:delete'])" @click="handleDeleteRole(element)">删除</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
            </template>
          </RuifoxTable>
          <PaginationViewSimple :total="queryData.total" :pageSize="queryData.pageSize" :currentPage="queryData.currentPage" @currentChange="handleCurrentChange" @changeSize="handleSizeChange" />
        </el-col>
      </el-row>
    </div>
    <!-- 添加团队 -->
    <el-dialog v-model="oStructureDialog" :title="oStructureTitle + '团队'" width="500px">
      <el-form :model="oStructureForm" ref="oStructureRef" :rules="oStructureRules" label-width="auto">
        <el-form-item label="上级团队" prop="pid">
          <el-tree-select
            v-model="oStructureForm.pid"
            :data="pTreeData"
            filterable
            clearable
            node-key="id"
            check-strictly
            default-expand-all
            :render-after-expand="false"
            :props="treeProps"
            placeholder="请选择上级团队，不选则为根目录"
            style="width: 100%"
          />
        </el-form-item>
        <el-form-item label="团队名称" prop="name">
          <el-input v-model="oStructureForm.name" placeholder="请填写团队名称" />
        </el-form-item>
        <el-form-item label="团队类型" prop="type">
          <el-select v-model="oStructureForm.type" placeholder="请选择" style="width: 100%">
            <el-option v-for="(item, index) in groupTypeList" :key="index" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="团队设置" prop="setting">
          <el-input v-model="oStructureForm.setting" type="textarea" :rows="20" placeholder="请输入团队配置，注意json格式，键名必须用双引号包裹" style="width: 100%" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="oStructureDialog = false">取消</el-button>
          <el-button type="primary" @click="oStructureSubmit(oStructureRef)">确定</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 转移团队 -->
    <el-dialog v-model="transferDialog" title="团队选择" width="500px">
      <el-form>
        <el-form-item label="转移到" prop="pid">
          <el-tree-select
            v-model="transferForm.groupId"
            :data="treeData"
            clearable
            node-key="id"
            check-strictly
            :render-after-expand="false"
            :props="treeProps"
            placeholder="请选择目标团队"
            style="width: 100%"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="transferDialog = false">取消</el-button>
          <el-button type="primary" @click="transferConfirm">确定</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 添加用户 -->
    <el-dialog v-model="isShowUserDialog" :title="userFormWay === 1 ? '添加用户' : '编辑用户'" width="30%" :close-on-click-modal="false">
      <el-form ref="userFormRule" :rules="userRules" :model="userData" label-width="100px" label-position="left" :inline-message="true">
        <!-- 头像、用户名称、登录账号的左右布局部分 -->
        <div class="user-info-section">
          <div class="avatar-section">
            <div class="img-box" @click="showAvatarDialog = true">
              <div class="avatar-mask">
                <p>点击修改头像</p>
              </div>
              <div class="no-avatar" v-if="!userData.avatar">
                <p>设置头像</p>
              </div>
              <div v-else class="has-avatar">
                <img :src="libPath + userData.avatar" alt="" />
              </div>
            </div>
          </div>
          <div class="info-section">
            <el-form-item label="">
              <template #label>
              </template>
              <el-input v-model="userData.name" placeholder="请输入用户名称"></el-input>
            </el-form-item>
            <el-form-item label="">
              <template #label>
              </template>
              <el-input v-model="userData.account" placeholder="请输入登录账号"></el-input>
            </el-form-item>
          </div>
        </div>
        <el-divider border-style="dashed" style="margin: 20px 0"/>
        <el-form-item label="所属角色：" prop="roleIds">
          <el-select v-model="userData.roleIds" class="m-2" placeholder="请选择所属角色" multiple style="width: 100%">
            <el-option v-for="item in roleList" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="所属团队：" prop="groupId" :required="userInfo.isSystem ? false : true">
          <el-tree-select v-model="userData.groupId" :data="treeData" :props="oStructureTreeProps" :expand-on-click-node="false" node-key="id" default-expand-all check-strictly style="width: 100%" />
        </el-form-item>
        <el-form-item label="密码：" prop="password">
          <el-button @click="resetPassword" v-show="!isResetPass && userFormWay !== 1">重置密码</el-button>
          <el-input v-model="userData.password" readonly v-show="isResetPass || userFormWay === 1">
            <template #append v-if="userFormWay !== 1">
              <div class="done-reset-password" v-if="isResetPass">
                <i class="iconfont">&#xe655;</i>
                已重置
              </div>
            </template>
            <template #append v-else>
              <div class="reset-password" @click="initPassword" v-if="!isInitPass">生成密码</div>
              <div class="done-reset-password" v-if="isInitPass">
                <i class="iconfont">&#xe655;</i>
                已生成
              </div>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="" v-if="(isInitPass && userFormWay === 1) || (isResetPass && userFormWay !== 1)">
          <el-switch v-model="userData.send_note"></el-switch>
          <span class="switch-send-note">是否发送密码给手机号</span>
        </el-form-item>
        <el-form-item label="接口调用">
          <el-switch v-model="userData.isUseInterface"></el-switch>
        </el-form-item>
        <el-form-item label="描述：" prop="introduction">
          <el-input v-model="userData.introduction" type="textarea"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="isShowUserDialog = false">取消</el-button>
          <el-button type="primary" @click="submitUserForm(userFormRule)">确认</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 用户权限 -->
    <el-dialog v-model="permissionDialog" title="用户权限" width="20%" @close="resetDisable">
      <p style="margin-bottom: 10px; font-size: 12px">用于单独分配菜单，禁用选项为所属角色所拥有的菜单</p>
      <el-tree v-loading="permissionLoading" ref="permissionRef" :data="permissionTree" :props="permissionTreeProps" show-checkbox :indent="10" node-key="id"></el-tree>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="submitPermission">确认</el-button>
          <el-button @click="permissionDialog = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 绑定策略 -->
    <StrategyBind v-if="showStrategy" v-model="showStrategy" :userId="userData.id" @success="getTableData" />
    <!-- 单独绑定资源 -->
    <ResourceBind v-if="showResourceAuth" v-model:show="showResourceAuth" :userId="userData.id" @success="getTableData" />
    <!-- 添加头像选择对话框 -->
    <el-dialog v-model="showAvatarDialog" title="头像选择">
      <div class="avatar-list">
        <div class="online-upload-item" :class="{ 'is-choose': userData.avatar === item }" v-for="item in avatarList" :key="item" @click="handleChooseAvatar(item)">
          <img :src="libPath + item" alt="" />
          <div class="upload-item-checkbox">
            <el-icon><Check /></el-icon>
          </div>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="showAvatarDialog = false">确认</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { selectGroupList, insertGroup, updateGroup, deleteGroup } from '@/api/team'
import { getRoleList, getRoleCratedBySelf, getMenuByUserId, getMenuList } from '@/api/role'
import { getUserPage, updateBatchGroupId, detectionAccount, userAdd, userDelete, userBan, userEdit, bindUserMenu, getRoleMenusByUserId } from '@/api/user'
import { sysFileSelectList } from '@/api/file'
import { tableList as mixTable, createTreeData, hasPermission } from '@ruifox-cms/utils'
import { useStore } from 'vuex'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Check } from '@element-plus/icons-vue'
import StrategyBind from './components/StrategyBind'
import ResourceBind from './components/ResourceBind'

/**
 * 这个功能部分页面和逻辑是从php后台迁移过来的，逻辑类似，php那边叫做组织架构，java这边叫做团队管理，所以有的变量、功能命名从字面上看着跟团队管理不搭嘎
 */
const { queryData, tableData, tableLoading, getTableData, handleSearch, handleCurrentChange, handleSizeChange, checkedList } = mixTable({
  getListApi: getUserPage
})
// 当前用户是否系统团队以及团队ID
const store = useStore()
const userInfo = computed(() => store.getters.userInfo)
// 团队类型
const groupTypeList = reactive([
  { label: '其他', value: 0 },
  { label: '医院', value: 1 },
  { label: '团队', value: 2 },
  { label: '科室', value: 3 }
])
const treeProps = {
  label: 'name',
  value: 'id',
  children: 'children'
}
const settingValidator = (rule, value, callback) => {
  try {
    JSON.parse(value)
    callback()
  } catch (error) {
    callback(new Error('请输入正确的json格式,检查键名键值是否用双引号包裹'))
  }
}
const oStructureRules = reactive({
  name: [{ required: true, message: '请输入团队名称', trigger: 'blur' }],
  type: [{ required: true, message: '请选择团队类型', trigger: 'change' }],
  setting: [{ required: true, validator: settingValidator, trigger: 'blur' }]
})

const oStructureTreeProps = {
  children: 'children',
  label: function (data) {
    return data.name
  }
}

// 用户列表可搜索字段
const treeData = ref([])
const pTreeData = ref([{ id: 0, name: '根目录', children: [] }])
const searchCmpArray = ref([
  { label: '账号', key: 'account' },
  { label: '用户姓名', key: 'name' },
  { label: '所属团队', key: 'groupId', form_type: 'treeSelect', options: treeData.value, props: { label: 'name', value: 'id' } }
])

// 获取团队列表
const treeLoading = ref(false)
const handleGetOStructure = async () => {
  treeLoading.value = true
  let res = await selectGroupList().finally(() => {
    treeLoading.value = false
  })
  const tree= createTreeData(res.data)
  treeData.value = tree
  
  pTreeData.value[0].children = tree
  searchCmpArray.value[2].options = treeData.value
}
handleGetOStructure()

// 新增
const defaultOStructureForm = {
  name: '', //名称
  pid: null, //上级组织id
  type: null,
  setting: "{}"
}
const oStructureForm = ref({})
const oStructureTitle = ref('新增')
const oStructureDialog = ref(false)
const handleAdd = data => {
  oStructureTitle.value = '新增'
  oStructureForm.value = structuredClone(defaultOStructureForm)
  if (data) oStructureForm.value.pid = data.id
  oStructureDialog.value = true
  if (oStructureRef.value) oStructureRef.value.clearValidate()
}

// 编辑
const handleEdit = data => {
  oStructureForm.value = structuredClone(data)
  oStructureTitle.value = '编辑'
  oStructureDialog.value = true
}

// 删除
const handleDelete = async data => {
  ElMessageBox.confirm('<div><p style="font-size: 16px;margin-bottom: 15px;">是否删除所选团队？</p><span style="font-size: 14px;color: #FF5240;">删除后团队将被移除</span></div>', '删除确认', {
    dangerouslyUseHTMLString: true,
    confirmButtonText: '确认',
    cancelButtonText: '取消'
  }).then(async () => {
    let res = await deleteGroup({ id: data.id })
    if (res.code == 20000) {
      ElMessage({
        showClose: true,
        message: `删除成功`,
        type: 'success'
      })
      handleGetOStructure()
    }
  })
}

// 提交
const oStructureRef = ref()
const oStructureSubmit = async formEl => {
  if (!formEl) return
  await formEl.validate(async valid => {
    if (valid) {
      let res = null
      if (!oStructureForm.value.id) {
        res = await insertGroup(oStructureForm.value)
      } else {
        res = await updateGroup(oStructureForm.value)
      }
      if (res.code == 20000) {
        ElMessage({
          showClose: true,
          message: `${oStructureTitle.value}成功`,
          type: 'success'
        })
        oStructureDialog.value = false
        handleGetOStructure()
      }
    }
  })
}

// 点击团队tree，获取人员列表
const curOStructure = ref()
const treeNodeClick = data => {
  if (curOStructure.value && data.id === curOStructure.value.id) return
  curOStructure.value = data
  queryData.groupId = data.id
  getTableData()
}

// 查看所有人员
const showAllUser = () => {
  curOStructure.value = null
  queryData.groupId = userInfo.value.isSystem ? null : userInfo.value.groupId
  getTableData()
}

/********************************************************组织用户列表相关**************************/
// 获取角色列表（非系统用户只能查看自己）
const roleList = ref([])
const _getRoleList = async () => {
  let res
  if (userInfo.value.isSystem) {
    res = await getRoleList()
  } else {
    res = await getRoleCratedBySelf()
  }
  if (res.code === 20000) {
    roleList.value = res.data
  }
}
// 人员列表展示字段
const fieldList = ref([
  {
    title: 'ID',
    name: 'id',
    width: 60
  },
  {
    title: '用户名称',
    name: 'name',
    showTextTip: true,
    width: 200
  },
  {
    title: '用户账号',
    name: 'account'
  },
  {
    title: '是否启用',
    name: 'isBan',
    width: 100
  },
  {
    title: '所属角色',
    name: 'roleNames'
  },
  {
    title: '组织团队',
    name: 'groupName'
  },
  {
    title: '操作',
    width: 240,
    fixed: 'right',
    name: 'options'
  }
])

// 获取用户列表
const defaultQueryData = {
  currentPage: 1,
  pageSize: 15,
  groupId: userInfo.value.isSystem ? null : userInfo.value.groupId
}
Object.assign(queryData, defaultQueryData)

// 勾选用户
const handleCheckTable = id => {
  if (checkedList.value.includes(id)) {
    checkedList.value = checkedList.value.filter(item => item != id)
  } else {
    checkedList.value.push(id)
  }
}

// 批量转移
const transferForm = ref({})
const transferDialog = ref(false)
const handleTransfer = () => {
  transferDialog.value = true
  transferForm.value.ids = checkedList.value
}
const transferConfirm = async () => {
  if (!transferForm.value.groupId && transferForm.value.groupId !== 0) {
    ElMessage.error('请选择要转移的团队')
  }
  const res = await updateBatchGroupId(transferForm.value)
  if (res.code === 20000) {
    ElMessage.success('转移成功')
    transferDialog.value = false
    getTableData()
  }
}

// 添加用户
const defaultUserData = {
  id: null,
  roleIds: [], //角色
  groupId: null,
  name: '', //名称
  account: '', //用户名
  password: '', //初始密码 or 密码
  isUseInterface: true, //是否使用接口调用
  avatar: '', //头像
  introduction: '', //描述
  send_note: false //发送短信
}
const userData = reactive(Object.assign({}, defaultUserData))
// 手机号验证
const validatorPhoneNumber = async (rule, value, callback) => {
  let reg = /^1[3-9]\d{9}$/
  if (value === '') {
    callback(new Error('请输入手机号账号'))
  } else if (!reg.test(value)) {
    callback(new Error('请输入正确的手机号'))
  } else if (userFormWay.value === 1) {
    let res = await detectionAccount({ account: value })
    if (res.data.is_exist === 1) {
      callback(new Error('手机号已存在'))
    } else {
      callback()
    }
  } else {
    let res = await detectionAccount({ account: value, id: userData.id })
    if (res.data.is_exist === 1) {
      callback(new Error('手机号已存在'))
    } else {
      callback()
    }
  }
}
// 密码验证 如果是编辑则密码不需要为空验证
const validatorPassword = async (rule, value, callback) => {
  if (value === '' && userFormWay.value === 1) {
    callback(new Error('请生成密码'))
  } else {
    callback()
  }
}
// 表单
const optionLoading = ref(false) //操作状态
const userFormRule = ref()
const userRules = reactive({
  roleIds: [{ required: true, message: '请选择所属角色', trigger: 'blur' }],
  name: [{ required: true, message: '请输入用户名称', trigger: 'blur' }],
  account: [{ required: true, validator: validatorPhoneNumber, trigger: 'blur' }],
  password: [{ validator: validatorPassword, trigger: 'blur' }],
  groupId: [{ required: true, message: '请选择所属团队', trigger: 'blur' }]
})
const isShowUserDialog = ref(false)
const userFormWay = ref(1) //修改还是添加 1:添加 2:修改
const isInitPass = ref(false)
//添加用户
const handleAddUser = () => {
  if (userFormRule.value) {
    userFormRule.value.resetFields()
  }

  Object.assign(userData, defaultUserData)
  isInitPass.value = false
  userFormWay.value = 1
  isShowUserDialog.value = true
}
//编辑用户
const handleEditUser = data => {
  if (userFormRule.value) {
    userFormRule.value.resetFields()
  }
  //赋值
  Object.assign(userData, defaultUserData)
  Object.assign(userData, data)
  isResetPass.value = false
  userFormWay.value = 2
  userData.send_note = false
  isShowUserDialog.value = true
}
const isResetPass = ref(false)
const resetPassword = () => {
  isResetPass.value = true
  userData.send_note = true
  userData.password = generatePassword(10)
  if (userFormRule.value) {
    userFormRule.value.validateField('password')
  }
}
const initPassword = () => {
  isInitPass.value = true
  userData.send_note = true
  userData.password = generatePassword(10)
  if (userFormRule.value) {
    userFormRule.value.validateField('password')
  }
}
const generatePassword = (length) => {
  const lowercase = 'abcdefghijklmnopqrstuvwxyz'
  const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  const numbers = '0123456789'
  const special = '!@#$%^&*'
  
  // 所有可用字符
  const allChars = lowercase + uppercase + numbers + special
  
  // 确保至少包含三种字符类型
  let password = ''
  const charTypes = [lowercase, uppercase, numbers, special]
  
  // 随机选择3种字符类型
  const selectedTypes = charTypes
    .sort(() => Math.random() - 0.5)
    .slice(0, 3)
  
  // 从每种选中的类型中至少选择一个字符
  selectedTypes.forEach(type => {
    password += type.charAt(Math.floor(Math.random() * type.length))
  })
  
  // 填充剩余长度
  while (password.length < length) {
    password += allChars.charAt(Math.floor(Math.random() * allChars.length))
  }

  return password
    .split('')
    .sort(() => Math.random() - 0.5)
    .join('')
}
const submitUserForm = async formEl => {
  if (!formEl) return
  optionLoading.value = true
  await formEl.validate(valid => {
    if (valid) {
      if (userFormWay.value === 1) {
        delete userData.id
        userAdd(userData).then(res => {
          if (res.code === 20000) {
            optionLoading.value = false
            isShowUserDialog.value = false
            ElMessage({
              showClose: true,
              message: '添加成功',
              type: 'success'
            })
            getTableData()
          }
        })
      } else {
        if (!isResetPass.value) delete userData.password
        userEdit(userData).then(res => {
          if (res.code === 20000) {
            optionLoading.value = false
            isShowUserDialog.value = false
            ElMessage({
              showClose: true,
              message: '修改成功',
              type: 'success'
            })
            getTableData()
          }
        })
      }
    }
  })
}
const handleDeleteRole = data => {
  ElMessageBox.confirm('<div><p style="font-size: 16px;margin-bottom: 15px;">是否删除所选用户？</p><span style="font-size: 14px;color: #FF5240;">删除后用户将被移除</span></div>', '删除确认', {
    dangerouslyUseHTMLString: true,
    confirmButtonText: '确认',
    cancelButtonText: '取消'
  }).then(() => {
    userDelete({ id: data.id }).then(() => {
      //更新节点
      getTableData()
      ElMessage({
        showClose: true,
        message: '删除成功',
        type: 'success'
      })
    })
  })
}

const beforeChange = data => {
  return new Promise(resolve => {
    // state === 1表示禁用
    let params = {
      id: data.id,
      isBan: data.state === 1 ? false : true
    }
    userBan(params)
      .then(res => {
        if (res.code === 20000) {
          ElMessage({
            type: 'success',
            message: '操作成功'
          })
          resolve(true)
        } else {
          ElMessage({
            type: 'error',
            message: '操作失败，请稍后再试'
          })
          resolve(false)
        }
      })
      .catch(() => {
        resolve(false)
      })
  })
}

// 编辑用户菜单权限
const permissionTree = ref([])
const permissionTreeProps = ref({
  children: 'children',
  label: function (data) {
    return data.title
  },
  disabled: function (data) {
    return disablePermission.value.includes(data.id)
  }
})

// 获取当前用户的所有菜单权限，每个用户进行权限分配只能基于自身权限
const initPermissionTree = async () => {
  let res
  if (userInfo.value.isSystem) {
    res = await getMenuList()
  } else {
    res = await getMenuByUserId({ id: userInfo.value.id })
  }
  if (res.code === 20000) {
    permissionTree.value = createTreeData(res.data)
  }
}
const permissionRef = ref(null)
const permissionForm = ref({})
const permissionDialog = ref(false)
const permissionLoading = ref(false)
const disablePermission = ref([])
const handleEditPermission = async row => {
  permissionDialog.value = true
  permissionLoading.value = true
  permissionForm.value.userId = row.id
  const res = await getMenuByUserId({ userId: row.id })
  let menuIds = []
  if (res.code === 20000) {
    menuIds = res.data ? res.data.map(item => item.id) : []
  }
  const res2 = await getRoleMenusByUserId({ userId: row.id })
  if (res2.code === 20000) {
    disablePermission.value = res2.data ? res2.data.map(item => item.id) : []
  }
  const checked = [...menuIds, ...disablePermission.value]
  permissionRef.value.setCheckedKeys(checked)
  permissionLoading.value = false
}
// 更新用户菜单权限
const submitPermission = () => {
  const menusIds = permissionRef.value.getCheckedKeys()
  permissionForm.value.menuIds = menusIds
  bindUserMenu(permissionForm.value).then(res => {
    if (res.code === 20000) {
      ElMessage({
        showClose: true,
        message: '修改成功',
        type: 'success'
      })
      permissionDialog.value = false
    }
  })
}

const resetDisable = () => {
  disablePermission.value = []
}

// 编辑用户策略绑定
const showStrategy = ref(false)
const handleBindResourceAuthGroup = data => {
  Object.assign(userData, data)
  showStrategy.value = true
}

// 单独分配资源权限
const showResourceAuth = ref(false)
const handleEditResourceAuth = (data) => {
  Object.assign(userData, data)
  showResourceAuth.value = true
}

// 头像相关
const libPath = computed(() => {
  if (!store.state.base.groupSetting.commonResources) return ''
  const env = 'libPath_' + process.env.NODE_ENV
  const url = store.state.base.groupSetting.commonResources[env]
  return url
})
const avatarList = ref([])
const showAvatarDialog = ref(false)

// 获取头像列表
const getAvatarList = async () => {
  const res = await sysFileSelectList({
    bucketName: 'lib',
    prefix: 'images/avatar/'
  })
  if (res.code === 20000) {
    avatarList.value = res.data
  }
}

// 选择头像
const handleChooseAvatar = avatar => {
  if (avatar === userData.avatar) userData.avatar = ''
  else userData.avatar = avatar
}

onMounted(() => {
  initPermissionTree()
  _getRoleList()
  handleGetOStructure()
  getTableData()
  getAvatarList()
})
</script>

<style scoped lang="scss">
.os-container {
  .content-box {
    min-height: 70vh;
    border: 1px $borderColor solid;
    ::v-deep(.el-scrollbar__view) {
      height: 100%;
    }
    .menu-tree-box {
      overflow: hidden;
      border-right: 1px solid $borderColor;
      .custom-tree-node {
        display: flex;
      }
      .tree-header {
        height: 53px;
        background-color: $backBase;
        border-bottom: 1px solid $borderColor;
        padding-left: 46px;
        display: flex;
        align-items: center;
        justify-content: space-between;
      }
      .tree-content {
        ::v-deep .el-tree-node .el-tree-node__content {
          border-bottom: 1px solid $borderColor;
          height: 48px;
        }
        ::v-deep .el-tree-node__label {
          width: 100%;
          .custom-tree-node {
            display: flex;
            justify-content: space-between;
            align-items: center;
            width: 100%;
            .tree-node-label {
              width: calc(100% - 16px - 26px);
              white-space: nowrap;
              overflow: hidden;
              text-overflow: ellipsis;
            }
            .tree-options {
              display: flex;
              padding-right: 10px;
              flex-shrink: 0;
            }
          }
        }
      }
    }
    .user-table {
      ::v-deep(.el-scrollbar.table-srollbar) {
        height: calc(100vh - 288px - 65px);
      }
      .user-table-top {
        padding: 15px;
        background: #dfe9f5;
        display: flex;
        justify-content: space-between;
        .top-left {
          .curOStructure {
            color: #666;
          }
          .user-default-show {
            color: #666;
          }
          .user-total {
            color: $mainColor;
          }
        }
      }
    }
  }
}

.avatar-list {
  display: flex;
  flex-wrap: wrap;
  height: 375px;
  padding: 10px;
  overflow-y: auto;
  
  .online-upload-item {
    border: 1px solid #e4e4e4;
    height: 160px;
    width: calc(20% - 16px);
    background-color: $backBase;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 8px;
    cursor: pointer;
    box-sizing: border-box;
    transition: all 0.3s;
    position: relative;
    
    .upload-item-checkbox {
      position: absolute;
      height: 24px;
      width: 24px;
      box-sizing: border-box;
      border: 1px solid #dcdfe6;
      top: 5px;
      left: 5px;
      background-color: $white;
      display: none;
      transition: all 0.2s;
      align-items: center;
      justify-content: center;
      i {
        font-weight: bold;
        font-size: 18px;
        color: $white;
      }
    }
    
    img {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
    }
    
    &.is-choose {
      .upload-item-checkbox {
        display: flex;
        background-color: #2cbf77;
        border-color: #2cbf77;
      }
    }
    
    &:hover {
      background-color: $focusContent;
      border-color: $hoverColor;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
      .upload-item-checkbox {
        display: flex;
      }
    }
  }
}

.user-info-section {
  display: flex;
  align-items: center;
  gap: 20px;
  ::v-deep(.el-form-item .el-form-item__label) {
    display: none;
  }
  
  .avatar-section {
    flex: 0 0 80px;
    border-radius: 4px;
    overflow: hidden;
    .img-box {
      height: 80px;
      width: 80px;
      cursor: pointer;
      overflow: hidden;
      position: relative;
      
      .no-avatar {
        display: flex;
        background-color: $mainColor;
        height: 100%;
        width: 100%;
        justify-content: center;
        align-items: center;
        p {
          color: #fff;
          font-size: 14px;
        }
      }
      
      .has-avatar {
        height: 100%;
        width: 100%;
        border-radius: 4px;
        img {
          height: 100%;
          width: 100%;
          border-radius: 4px;
        }
      }
      
      &:hover {
        .avatar-mask {
          opacity: 1;
        }
      }
      
      .avatar-mask {
        transition: all 0.3s;
        opacity: 0;
        position: absolute;
        width: 100%;
        height: 100%;
        background-color: rgba(#000, 0.4);
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 4px;
        p {
          text-align: center;
          font-size: 14px;
          color: #fff;
        }
      }
    }
  }

  .info-section {
    flex: 1;
    
    .el-form-item {
      margin-bottom: 18px;
      
      &:last-child {
        margin-bottom: 0;
      }
    }
  }
}

.role-names-box {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.group-name-box {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
</style>
